package com.pactera.madp.admin.service.impl;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pactera.madp.admin.api.dto.LineDeptUserDTO;
import com.pactera.madp.admin.api.entity.SysDeptRelation;
import com.pactera.madp.admin.api.entity.SysDeptUser;
import com.pactera.madp.admin.api.vo.SysDeptVo;
import com.pactera.madp.admin.mapper.SysDeptUserMapper;
import com.pactera.madp.admin.service.SysDeptRelationService;
import com.pactera.madp.admin.service.SysDeptUserService;
import com.pactera.madp.admin.service.SysUserService;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * <p>
 * 条线部门 - 用户表 服务实现类
 * </p>
 *
 * @author huhao
 * @since 2022-03-02
 */
@Service
@AllArgsConstructor
public class SysDeptUserServiceImpl extends ServiceImpl<SysDeptUserMapper, SysDeptUser> implements SysDeptUserService {

    private final SysDeptRelationService sysDeptRelationService;

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean updateUsersToLineDept(LineDeptUserDTO dto) {
        List<Integer> selectUserIds = dto.getSelectUserIds();
        List<Integer> selectLineDeptIds = dto.getSelectLineDeptIds();
        // 获取需要调整的条线部门所有子孙条线
        List<Integer> childrens1 = sysDeptRelationService.list(
                Wrappers.<SysDeptRelation>lambdaQuery()
                        .eq(SysDeptRelation::getAncestor, dto.getLineDeptId())
        ).stream().map(SysDeptRelation::getDescendant).collect(Collectors.toList());

        // 遍历条线部门调整集合
        for (Integer selectLineDeptId : new ArrayList<>(selectLineDeptIds)) {
            List<SysDeptRelation> childrens = sysDeptRelationService.list(
                    Wrappers.<SysDeptRelation>lambdaQuery()
                            .eq(SysDeptRelation::getAncestor, selectLineDeptId)
//                    .and(wrapper -> wrapper.ne(SysDeptRelation::getDescendant, selectLineDeptId))
            );
            // 条线部门的子孙条线也为调整状态
            selectLineDeptIds.addAll(childrens.stream().map(SysDeptRelation::getDescendant).collect(Collectors.toList()));
        }
        childrens1.removeIf(s -> selectLineDeptIds.contains(s));

        if (childrens1 != null && childrens1.size() > 0)
            this.update(Wrappers.<SysDeptUser>lambdaUpdate()
                    .set(SysDeptUser::getIsSelect, "0")
                    .in(SysDeptUser::getDeptId, childrens1)
            );
        // 条线部门调整
        if (selectLineDeptIds != null && selectLineDeptIds.size() > 0)
            this.update(Wrappers.<SysDeptUser>lambdaUpdate()
                    .set(SysDeptUser::getIsSelect, "1")
                    .in(SysDeptUser::getDeptId, selectLineDeptIds)
            );
        // 条线成员调整
        if (selectUserIds != null && selectUserIds.size() > 0)
            this.update(Wrappers.<SysDeptUser>lambdaUpdate()
                    .set(SysDeptUser::getIsSelect, "1")
                    .in(SysDeptUser::getUserId, selectUserIds)
            );
        return Boolean.TRUE;
    }

    @Override
    public SysDeptVo getLineDeptSelected(Integer deptId) {
        // 获取以deptId为根节点的部门树所有部门id集合，以该集合为基础获取部门调整的部门集合
        List<SysDeptRelation> sysDeptRelations = sysDeptRelationService.list(
                Wrappers.<SysDeptRelation>lambdaQuery()
                        .select(SysDeptRelation::getDescendant, SysDeptRelation::getAncestor)
                        .eq(SysDeptRelation::getAncestor, deptId)
        );
        if (sysDeptRelations == null || sysDeptRelations.size() == 0)
            return null;

        // 获取部门树所有部门-成员调整关系
        List<SysDeptUser> sysDeptUsers = this.list(
                Wrappers.<SysDeptUser>lambdaQuery()
                        .in(SysDeptUser::getDeptId, sysDeptRelations.stream().map(SysDeptRelation::getDescendant).collect(Collectors.toList())));
        if (sysDeptUsers == null || sysDeptUsers.size() == 0)
            return null;
        // 获取已存在成员调整的部门集合
//        Set<Integer> lineDeptIds = new HashSet<>();
//        for (SysDeptUser sysDeptUser : sysDeptUsers) {
//            lineDeptIds.add(sysDeptUser.getDeptId());
//        }
        Set<Integer> lineDeptIds = sysDeptUsers.stream().map(SysDeptUser::getDeptId).collect(Collectors.toSet());
        Set<Integer> removeIds = new HashSet<>();
        outer:
        for (Integer lineDeptId : lineDeptIds) {
            inner:
            for (SysDeptUser sysDeptUser : sysDeptUsers) {
                // 如果部门下有一个成员调整状态为0
                if (lineDeptId.equals(sysDeptUser.getDeptId()) && "0".equals(sysDeptUser.getIsSelect())) {
                    // 该部门及其所有上层节点部门调整状态都应为未调整，都移除
                    // 移除自己
                    removeIds.add(lineDeptId);
                    // 移除上级
                    sysDeptRelations.forEach(
                            s -> {
                                if (s.getDescendant().equals(lineDeptId)) {
                                    removeIds.add(s.getAncestor());
                                }
                            }
                    );
//                    sysDeptRelations.removeIf(s -> {
//                        Integer parentId = s.getAncestor();
//                        s.getDescendant().equals(lineDeptId);
//                        return true;
//                    });
                    // 移除下级
//                    sysDeptRelations.removeIf(s -> s.getAncestor().equals(lineDeptId));
                    break inner;
                }
            }
        }
        sysDeptRelations.removeIf(s -> removeIds.contains(s.getDescendant()));
        List<Integer> selectLineDeptIds = sysDeptRelations.stream().map(SysDeptRelation::getDescendant).collect(Collectors.toList());
        // 获取最后的成员调整的成员集合
        // 移除部门调整的
        sysDeptUsers.removeIf(s -> selectLineDeptIds.contains(s.getDeptId()));
        // 移除调整状态为0的
        sysDeptUsers.removeIf(s -> "0".equals(s.getIsSelect()));
        List<Integer> selectUserIds = sysDeptUsers.stream().map(SysDeptUser::getUserId).collect(Collectors.toList());
        // 获取最后的部门调整集合，一个部门下所有部门为调整状态，则返回该部门，而不返回其所有下级部门
        List<Integer> lastSelectLineDeptIds = new ArrayList<>(selectLineDeptIds);
        selectLineDeptIds.forEach(s -> {
            // 此处当可优化下
            List<Integer> childrens = sysDeptRelationService.list(
                    Wrappers.<SysDeptRelation>lambdaQuery()
                            .select(SysDeptRelation::getDescendant)
                            .eq(SysDeptRelation::getAncestor, s)
                            .ne(SysDeptRelation::getDescendant, s)
            ).stream().map(SysDeptRelation::getDescendant).collect(Collectors.toList());
            if (selectLineDeptIds.containsAll(childrens)) {
                lastSelectLineDeptIds.removeAll(childrens);
            }/* else {
                lastSelectLineDeptIds.removeIf(s1 -> s1.equals(s));
            }*/
        });
        SysDeptVo sysDeptVo = new SysDeptVo();
        sysDeptVo.setSelectLineDeptIds(lastSelectLineDeptIds);
        sysDeptVo.setSelectUserIds(selectUserIds);
        return sysDeptVo;
    }

    @Override
    public SysDeptVo getLineDeptSelected1(Integer deptId) {
        // 获取以deptId为根节点的部门树所有部门id集合，以该集合为基础获取部门调整的部门集合
        List<SysDeptRelation> sysDeptRelations = sysDeptRelationService.list(
                Wrappers.<SysDeptRelation>lambdaQuery()
                        .select(SysDeptRelation::getDescendant, SysDeptRelation::getAncestor)
                        .eq(SysDeptRelation::getAncestor, deptId)
        );
        if (sysDeptRelations == null || sysDeptRelations.size() == 0)
            return null;
        // 获取部门树所有部门-成员调整关系
        List<SysDeptUser> sysDeptUsers = this.list(
                Wrappers.<SysDeptUser>lambdaQuery()
                        .in(SysDeptUser::getDeptId, sysDeptRelations.stream().map(SysDeptRelation::getDescendant).collect(Collectors.toList())));
        if (sysDeptUsers == null || sysDeptUsers.size() == 0)
            return null;
        sysDeptUsers.removeIf(s -> "0".equals(s.getIsSelect()));
        List<Integer> selectUserIds = sysDeptUsers.stream().map(SysDeptUser::getUserId).collect(Collectors.toList());
        SysDeptVo sysDeptVo = new SysDeptVo();
        sysDeptVo.setSelectUserIds(selectUserIds);
        return sysDeptVo;
    }

    @Override
    public SysDeptVo getLineDeptSelected1(List<Integer> deptIds) {
        // 获取以deptId为根节点的部门树所有部门id集合，以该集合为基础获取部门调整的部门集合
        List<SysDeptRelation> sysDeptRelations = sysDeptRelationService.list(
                Wrappers.<SysDeptRelation>lambdaQuery()
                        .select(SysDeptRelation::getDescendant, SysDeptRelation::getAncestor)
                        .in(SysDeptRelation::getAncestor, deptIds)
        );
        if (sysDeptRelations == null || sysDeptRelations.size() == 0)
            return null;
        // 获取部门树所有部门-成员调整关系
        List<SysDeptUser> sysDeptUsers = this.list(
                Wrappers.<SysDeptUser>lambdaQuery()
                        .in(SysDeptUser::getDeptId, sysDeptRelations.stream().map(SysDeptRelation::getDescendant).collect(Collectors.toList())));
        if (sysDeptUsers == null || sysDeptUsers.size() == 0)
            return null;
        sysDeptUsers.removeIf(s -> "0".equals(s.getIsSelect()));
        List<Integer> selectUserIds = sysDeptUsers.stream().map(SysDeptUser::getUserId).distinct().collect(Collectors.toList());
        SysDeptVo sysDeptVo = new SysDeptVo();
        sysDeptVo.setSelectUserIds(selectUserIds);
        return sysDeptVo;
    }

}